///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct  8 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////

#include "myframe.h"
#include <string>
#include "../Calibration/stereocalib.h"

using namespace std;

class StereoCalib;

///////////////////////////////////////////////////////////////////////////

MyFrame::MyFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxSize( 680,500 ), wxDefaultSize );
	
	wxBoxSizer* bSizer1;
	bSizer1 = new wxBoxSizer( wxHORIZONTAL );
	
	m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxBoxSizer* bSizer6;
	bSizer6 = new wxBoxSizer( wxVERTICAL );
	
	m_panel12 = new wxPanel( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer9;
	sbSizer9 = new wxStaticBoxSizer( new wxStaticBox( m_panel12, wxID_ANY, wxT("Display") ), wxVERTICAL );
	
	wxGridSizer* gSizer6;
	gSizer6 = new wxGridSizer( 0, 2, 0, 0 );
	
	m_panDisplay1 = new MyImagePanel( m_panel12, wxDefaultPosition, wxDefaultSize);
	gSizer6->Add( m_panDisplay1, 1, wxEXPAND | wxALL, 5 );
	
	m_panDisplay2 = new MyImagePanel( m_panel12, wxDefaultPosition, wxDefaultSize);
	gSizer6->Add( m_panDisplay2, 1, wxEXPAND | wxALL, 5 );
	
	
	sbSizer9->Add( gSizer6, 1, wxEXPAND, 5 );
	
	wxBoxSizer* bSizer17;
	bSizer17 = new wxBoxSizer( wxVERTICAL );
	
	m_panDisplay3 = new MyImagePanel( m_panel12,wxDefaultPosition, wxDefaultSize);
	bSizer17->Add( m_panDisplay3, 1, wxEXPAND | wxALL, 5 );
	
	
	sbSizer9->Add( bSizer17, 1, wxEXPAND, 5 );
	
	
	m_panel12->SetSizer( sbSizer9 );
	m_panel12->Layout();
	sbSizer9->Fit( m_panel12 );
	bSizer6->Add( m_panel12, 1, wxEXPAND | wxALL, 5 );
	
	
	m_panel1->SetSizer( bSizer6 );
	m_panel1->Layout();
	bSizer6->Fit( m_panel1 );
	bSizer1->Add( m_panel1, 1, wxEXPAND, 5 );
	
	m_panel2 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxBoxSizer* bSizer4;
	bSizer4 = new wxBoxSizer( wxVERTICAL );
	
	m_panel7 = new wxPanel( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer1;
	sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_panel7, wxID_ANY, wxT("Camera 1") ), wxVERTICAL );
	
	wxBoxSizer* bSizer71;
	bSizer71 = new wxBoxSizer( wxHORIZONTAL );
	
	m_staticText1 = new wxStaticText( m_panel7, wxID_ANY, wxT("Status: "), wxDefaultPosition, wxDefaultSize, 0 );
	m_staticText1->Wrap( -1 );
	bSizer71->Add( m_staticText1, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_stxtCamStatus1 = new wxStaticText( m_panel7, wxID_ANY, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0 );
	m_stxtCamStatus1->Wrap( -1 );
	bSizer71->Add( m_stxtCamStatus1, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_btCamOpen1 = new wxButton( m_panel7, wxID_ANY, wxT("Open Camera"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer71->Add( m_btCamOpen1, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	
	sbSizer1->Add( bSizer71, 1, wxEXPAND, 5 );
	
	
	m_panel7->SetSizer( sbSizer1 );
	m_panel7->Layout();
	sbSizer1->Fit( m_panel7 );
	bSizer4->Add( m_panel7, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
	
	m_panel8 = new wxPanel( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer2;
	sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panel8, wxID_ANY, wxT("Camera 2") ), wxVERTICAL );
	
	wxBoxSizer* bSizer8;
	bSizer8 = new wxBoxSizer( wxHORIZONTAL );
	
	m_staticText11 = new wxStaticText( m_panel8, wxID_ANY, wxT("Status: "), wxDefaultPosition, wxDefaultSize, 0 );
	m_staticText11->Wrap( -1 );
	bSizer8->Add( m_staticText11, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_stxtCamStatus2 = new wxStaticText( m_panel8, wxID_ANY, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0 );
	m_stxtCamStatus2->Wrap( -1 );
	bSizer8->Add( m_stxtCamStatus2, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_btCamOpen2 = new wxButton( m_panel8, wxID_ANY, wxT("Open Camera"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer8->Add( m_btCamOpen2, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	
	sbSizer2->Add( bSizer8, 1, wxEXPAND, 5 );
	
	
	m_panel8->SetSizer( sbSizer2 );
	m_panel8->Layout();
	sbSizer2->Fit( m_panel8 );
	bSizer4->Add( m_panel8, 0, wxEXPAND | wxALL, 5 );
	
	m_panel121 = new wxPanel( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer6;
	sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( m_panel121, wxID_ANY, wxT("Image Capture") ), wxVERTICAL );
	
	wxGridSizer* gSizer3;
	gSizer3 = new wxGridSizer( 1, 2, 0, 0 );
	
	m_btCapture1 = new wxButton( m_panel121, wxID_ANY, wxT("Capture 1"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer3->Add( m_btCapture1, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_btCapture2 = new wxButton( m_panel121, wxID_ANY, wxT("Capture 2"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer3->Add( m_btCapture2, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_btCapturePair = new wxButton( m_panel121, wxID_ANY, wxT("Capture Pair"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer3->Add( m_btCapturePair, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_cbShowCorners = new wxCheckBox( m_panel121, wxID_ANY, wxT("Show Corners"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer3->Add( m_cbShowCorners, 0, wxALIGN_CENTER|wxALL, 5 );
	
	
	sbSizer6->Add( gSizer3, 1, wxEXPAND, 5 );
	
	
	m_panel121->SetSizer( sbSizer6 );
	m_panel121->Layout();
	sbSizer6->Fit( m_panel121 );
	bSizer4->Add( m_panel121, 1, wxEXPAND | wxALL, 5 );
	
	m_panel11 = new wxPanel( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer61;
	sbSizer61 = new wxStaticBoxSizer( new wxStaticBox( m_panel11, wxID_ANY, wxT("Calibration") ), wxVERTICAL );
	
	wxGridSizer* gSizer31;
	gSizer31 = new wxGridSizer( 0, 2, 0, 0 );
	
	m_btCalibCam1 = new wxButton( m_panel11, wxID_ANY, wxT("Calib Cam1"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer31->Add( m_btCalibCam1, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_btCalibCam2 = new wxButton( m_panel11, wxID_ANY, wxT("Calib Cam2"), wxDefaultPosition, wxDefaultSize, 0 );
	gSizer31->Add( m_btCalibCam2, 0, wxALIGN_CENTER|wxALL, 5 );
	
	
	sbSizer61->Add( gSizer31, 1, wxALIGN_CENTER|wxEXPAND, 5 );
	
	wxBoxSizer* bSizer9;
	bSizer9 = new wxBoxSizer( wxVERTICAL );
	
	m_btStereoCalib = new wxButton( m_panel11, wxID_ANY, wxT("Stereo Calibration"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer9->Add( m_btStereoCalib, 0, wxALIGN_CENTER|wxALL, 5 );
	
	
	sbSizer61->Add( bSizer9, 1, wxALIGN_CENTER|wxEXPAND, 5 );
	
	
	m_panel11->SetSizer( sbSizer61 );
	m_panel11->Layout();
	sbSizer61->Fit( m_panel11 );
	bSizer4->Add( m_panel11, 1, wxEXPAND | wxALL, 5 );
	
	m_panel10 = new wxPanel( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
	wxStaticBoxSizer* sbSizer4;
	sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_panel10, wxID_ANY, wxT("Stitching Options") ), wxVERTICAL );
	
	wxBoxSizer* bSizer7;
	bSizer7 = new wxBoxSizer( wxVERTICAL );
	
	m_cbStartStitching = new wxCheckBox( m_panel10, wxID_ANY, wxT("Start Stitching"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer7->Add( m_cbStartStitching, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_rbAuto = new wxRadioButton( m_panel10, wxID_ANY, wxT("Auto Stitch   "), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer7->Add( m_rbAuto, 0, wxALIGN_CENTER|wxALL, 5 );
	
	m_rbHomo = new wxRadioButton( m_panel10, wxID_ANY, wxT("Homography"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer7->Add( m_rbHomo, 0, wxALIGN_CENTER|wxALL, 5 );
	
	
	sbSizer4->Add( bSizer7, 1, wxEXPAND, 5 );
	
	
	m_panel10->SetSizer( sbSizer4 );
	m_panel10->Layout();
	sbSizer4->Fit( m_panel10 );
	bSizer4->Add( m_panel10, 0, wxEXPAND|wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
	
	
	m_panel2->SetSizer( bSizer4 );
	m_panel2->Layout();
	bSizer4->Fit( m_panel2 );
	bSizer1->Add( m_panel2, 0, wxEXPAND, 5 );
	
	
	this->SetSizer( bSizer1 );
	this->Layout();
	m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
	
	this->Centre( wxBOTH );
	
	// Connect Events
	m_btCamOpen1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::OpenCam1 ), NULL, this );
	m_btCamOpen2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::OpenCam2 ), NULL, this );
	m_btCapture1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CaptureCam1 ), NULL, this );
	m_btCapture2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CaptureCam2 ), NULL, this );
	m_btCapturePair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CapturePair ), NULL, this );
	m_cbShowCorners->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MyFrame::ShowCorners ), NULL, this );
	m_btCalibCam1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CalibCam1 ), NULL, this );
	m_btCalibCam2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CalibCam2 ), NULL, this );
	m_btStereoCalib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::RunStereoCalib ), NULL, this );
	m_cbStartStitching->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MyFrame::StartStitching ), NULL, this );
	m_rbAuto->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MyFrame::SelectAutoStitch ), NULL, this );
	m_rbHomo->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MyFrame::SelectHomography ), NULL, this );

	m_camera=NULL;
	m_startStitching=false;
	m_autoStitching=false;
	m_homoStitching=false;
	m_rbAuto->Disable();
	m_rbHomo->Disable();
	m_timeLabel=clock();
}

MyFrame::~MyFrame()
{
	// Disconnect Events
	m_btCamOpen1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::OpenCam1 ), NULL, this );
	m_btCamOpen2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::OpenCam2 ), NULL, this );
	m_btCapture1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CaptureCam1 ), NULL, this );
	m_btCapture2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CaptureCam2 ), NULL, this );
	m_btCapturePair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CapturePair ), NULL, this );
	m_cbShowCorners->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MyFrame::ShowCorners ), NULL, this );
	m_btCalibCam1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CalibCam1 ), NULL, this );
	m_btCalibCam2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::CalibCam2 ), NULL, this );
	m_btStereoCalib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MyFrame::RunStereoCalib ), NULL, this );
	m_cbStartStitching->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MyFrame::StartStitching ), NULL, this );
	m_rbAuto->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MyFrame::SelectAutoStitch ), NULL, this );
	m_rbHomo->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MyFrame::SelectHomography ), NULL, this );
	
	m_camera=NULL;
}

MyImagePanel* MyFrame::GetImagePanel1()
{
	return m_panDisplay1;
}

MyImagePanel* MyFrame::GetImagePanel2()
{
	return m_panDisplay2;
}

MyImagePanel* MyFrame::GetImagePanel3()
{
	return m_panDisplay3;
}

void MyFrame::OpenCam1(wxCommandEvent& event)
{
	if(m_camera->m_Cam1_isOpen)
	{
		m_camera->CloseCam1();
		m_stxtCamStatus1->SetLabel(wxT("Closed"));
		m_btCamOpen1->SetLabel(wxT("Open Camera"));

		m_statusBar->SetLabel(wxT("Camera 1 is Closed!"));
	}
	else
	{
		m_camera->OpenCam1();
		m_stxtCamStatus1->SetLabel(wxT("Open"));
		m_btCamOpen1->SetLabel(wxT("Close Camera"));

		m_statusBar->SetLabel(wxT("Camera 1 is Open!"));
	}
}

void MyFrame::OpenCam2(wxCommandEvent& event)
{
	if(m_camera->m_Cam2_isOpen)
	{
		m_camera->CloseCam2();
		m_stxtCamStatus2->SetLabel(wxT("Closed"));
		m_btCamOpen2->SetLabel(wxT("Open Camera"));

		m_statusBar->SetLabel(wxT("Camera 2 is Closed!"));
	}
	else
	{
		m_camera->OpenCam2();
		m_stxtCamStatus2->SetLabel(wxT("Open"));
		m_btCamOpen2->SetLabel(wxT("Close Camera"));

		m_statusBar->SetLabel(wxT("Camera 2 is Open!"));
	}
}

wxString MyFrame::GenStatus(String identity, int num)
{
	String status;
	String sNum = static_cast<ostringstream*>( &(ostringstream() << num) )->str();

	status="Image Captured Successfully from "+identity+":"+" Num "+sNum+".";

	wxString result(status.c_str(), wxConvUTF8);

	return result;
}

void MyFrame::SetStatusBar(String status)
{
	wxString result(status.c_str(), wxConvUTF8);

	m_statusBar->SetLabel(result);
}

void MyFrame::CaptureCam1(wxCommandEvent& event)
{
	if(m_camera->m_Cam1_isOpen)
	{
		if(m_camera->CaptureCam1())
		{
			m_statusBar->SetLabel(GenStatus("Cam1",m_camera->m_numImageCam1));
		}
	}
	else
		wxMessageBox(wxT("Please Open Camera 1 First!"));
}

void MyFrame::CaptureCam2(wxCommandEvent& event)
{
	if(m_camera->m_Cam2_isOpen)
	{
		if(m_camera->CaptureCam2())
			m_statusBar->SetLabel(GenStatus("Cam2",m_camera->m_numImageCam2));
	}
	else
		wxMessageBox(wxT("Please Open Camera 2 First!"));
}

void MyFrame::CapturePair(wxCommandEvent& event)
{
	if(m_camera->m_Cam1_isOpen && m_camera->m_Cam2_isOpen)
	{
		if(m_camera->CapturePair())
			m_statusBar->SetLabel(GenStatus("Pair",m_camera->m_numImagePair));
	}
	else
		wxMessageBox(wxT("Please Make Sure both Camera 1 and 2 are Open!"));
}

void MyFrame::ShowCorners(wxCommandEvent & event)
{
	if(m_camera->m_showCorners)
	{
		m_camera->m_showCorners=false;
		m_cbShowCorners->SetLabel(wxT("Show Corners"));
	}
	else
	{
		m_camera->m_showCorners=true;
		m_cbShowCorners->SetLabel(wxT("Hide Corners"));
	}
}

void MyFrame::RunStereoCalib(wxCommandEvent & event)
{
	StereoCalib stereoCalib;
	int flag;

	flag=stereoCalib.StereoCalibration();

	if(flag==0)
	{
		wxMessageBox(wxT("Stereos cameras are successfully calibrated!"));

	}
	else if(flag==-1)
		wxMessageBox(wxT("Error: the input image list is not specified, or can not be read, or the number of files is not divisible by 2!"));
	else if(flag==-2)
		wxMessageBox(wxT("Error: too little pairs to run the calibration!"));
}

void MyFrame::StartStitching( wxCommandEvent& event )
{
	if(m_cbStartStitching->IsChecked())
	{
		m_rbAuto->Enable();
		m_rbHomo->Enable();

		if(!m_rbAuto->GetValue() && !m_rbHomo->GetValue())
			m_rbHomo->SetValue(true);

		m_startStitching=true;
		m_homoStitching=true;

		m_statusBar->SetLabel(wxT("Start stitching!"));
	}
	else
	{
		m_startStitching=false;
		m_rbAuto->SetValue(false);
		m_rbHomo->SetValue(false);

		m_homoStitching=false;
		m_autoStitching=false;

		m_rbAuto->Disable();
		m_rbHomo->Disable();

		m_statusBar->SetLabel(wxT("End stitching!"));
	}
}

void MyFrame::SelectAutoStitch( wxCommandEvent& event )
{
	m_autoStitching=true;
	m_homoStitching=false;

	m_rbAuto->SetValue(true);
	m_rbHomo->SetValue(false);

	m_statusBar->SetLabel(wxT("Auto Stitching Method is Selected!"));
}

void MyFrame::SelectHomography( wxCommandEvent& event )
{
	m_autoStitching=false;
	m_homoStitching=true;

	m_rbHomo->SetValue(true);
	m_rbAuto->SetValue(false);

	m_statusBar->SetLabel(wxT("Stitching with Homography Method is Selected!"));
}
